const THRESHOLD = 0.3

// eslint-disable-next-line
Component({
    options: {
        multipleSlots: true
    },

    properties: {
        disabled: Boolean,
        leftWidth: {
            type: Number,
            value: 0
        },
        rightWidth: {
            type: Number,
            value: 0
        },
        asyncClose: Boolean
    },

    data: {
        catchMove: true,
        wrapperStyle: ''
    },

    created () {
        this.offset = 0
    },

    attached () {
        this.factor = wx.getSystemInfoSync().screenWidth / 750

        const { leftWidth, rightWidth } = this.data
        this.setData({
            leftWidth: this.toPx(leftWidth),
            rightWidth: this.toPx(rightWidth)
        })
    },

    methods: {
        startDrag (event) {
            if (this.data.disabled) {
                return
            }

            this.draging = true
            this.startOffset = this.offset
            this.firstDirection = ''
            this.touchStart(event)
        },
        onDrag (event) {
            if (this.data.disabled) {
                return
            }

            this.touchMove(event)

            if (!this.firstDirection) {
                this.firstDirection = this.direction
                this.setData({
                    catchMove: this.firstDirection === 'horizontal'
                })
            }

            if (this.firstDirection === 'vertical') {
                return
            }

            const { leftWidth, rightWidth } = this.data

            const offset = this.startOffset + this.deltaX

            if ((rightWidth > 0 && -offset > rightWidth) || (leftWidth > 0 && offset > leftWidth)) {
                return
            }

            this.swipeMove(offset)
        },
        endDrag () {
            if (this.data.disabled) {
                return
            }

            this.draging = false
            this.swipeLeaveTransition()
        },
        onClick (event) {
            const { key: position = 'outside' } = event.currentTarget.dataset
            this.triggerEvent('click', position)

            if (!this.offset) {
                return
            }

            if (this.data.asyncClose) {
                this.triggerEvent('close', { position: position, instance: this })
            } else {
                this.close()
            }
        },

        touchStart (event) {
            const touch = event.touches[0]
            this.direction = ''
            this.deltaX = 0
            this.deltaY = 0
            this.offsetX = 0
            this.offsetY = 0
            this.startX = touch.clientX
            this.startY = touch.clientY
        },
        touchMove (event) {
            const touch = event.touches[0]
            this.deltaX = touch.clientX - this.startX
            this.deltaY = touch.clientY - this.startY
            this.offsetX = Math.abs(this.deltaX)
            this.offsetY = Math.abs(this.deltaY)
            this.direction = this.offsetX > this.offsetY ? 'horizontal' : (this.offsetX < this.offsetY ? 'vertical' : '')
        },

        swipeMove (offset = 0) {
            this.offset = offset

            const transform = `translate3d(${offset}px, 0, 0)`
            const transition = this.draging ? 'none' : '.6s cubic-bezier(0.18, 0.89, 0.32, 1)'

            this.setData({
                wrapperStyle: `transform: ${transform};transition: ${transition};`
            })
        },
        swipeLeaveTransition () {
            const { leftWidth, rightWidth } = this.data
            const { offset } = this

            if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
                this.open('right')
            } else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
                this.open('left')
            } else {
                this.close()
            }
        },

        open (position = 'left') {
            const { leftWidth, rightWidth } = this.data
            const offset = position === 'left' ? leftWidth : -rightWidth
            this.swipeMove(offset)
        },
        close () {
            this.swipeMove(0)
        },
        noop () {},

        toPx (rpx) {
            return rpx * this.factor
        }
    }
})
